package com.alcohol.auth.server.support.core;

import com.alcohol.auth.server.config.AuthServerSecurityConfig;
import com.alcohol.auth.server.utils.HttpServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.RedirectUrlBuilder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;

/**
 * @author LiXinYu
 * @date 2025/11/17
 */
public class LoginTargetAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    public LoginTargetAuthenticationEntryPoint() {
        super(AuthServerSecurityConfig.LOGIN_PAGE);
    }

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
        MultiValueMap<String, String> requestParamMap = HttpServletUtils.getParameters(request);
        UriComponentsBuilder targetUrlBuilder = UriComponentsBuilder.fromUriString(resolveConsentUri(request));
        if (!CollectionUtils.isEmpty(requestParamMap)) {
            for (String key : requestParamMap.keySet()) {
                if (!StringUtils.pathEquals(key, OAuth2ParameterNames.REDIRECT_URI)) {
                    targetUrlBuilder.queryParam(key, requestParamMap.get(key));
                }
            }
        }

        this.redirectStrategy.sendRedirect(request, response, targetUrlBuilder.toUriString());
    }

    private String resolveConsentUri(HttpServletRequest request) {
        RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
        urlBuilder.setScheme(request.getScheme());
        urlBuilder.setServerName(request.getServerName());
        urlBuilder.setPort(request.getServerPort());
        urlBuilder.setContextPath(request.getContextPath());
        urlBuilder.setPathInfo(AuthServerSecurityConfig.LOGIN_PAGE);
        return urlBuilder.getUrl();
    }
}
